<template>
  <div class="container">
    <a-card class="custom-card" title="">
      <a-row>
        <a-col :flex="1">
          <a-form
            :model="query"
            :label-col-props="{ span: 6 }"
            :wrapper-col-props="{ span: 18 }"
            label-align="left"
          >
            <a-row :gutter="16">
              <a-col :span="6">
                <a-input v-model="query.name" placeholder="请输入名称" allow-clear>
                  <template #prepend>名称</template>
                </a-input>
              </a-col>
              <a-col flex="360px">
                <a-input-group>
                  <a-select v-model="query.time_type" placeholder="时间类型" :style="{width:'120px'}">
                    <a-option value="created_at" label="添加时间" />
                  </a-select>
                  <a-range-picker v-model="query.range_date" allow-clear/>
                </a-input-group>
              </a-col>
            </a-row>
          </a-form>
        </a-col>
        <a-divider style="height: 44px" direction="vertical" />
        <a-col :flex="'86px'" style="text-align: right">
          <a-space :size="18">
            <a-button type="primary" @click="search">
              <template #icon><icon-search /></template>搜索
            </a-button>
            <a-button status="success" @click="refresh()">
              <template #icon><icon-refresh /></template>重置
            </a-button>
          </a-space>
        </a-col>
      </a-row>
      <a-divider style="margin-top: 0" />
      <a-row style="margin-bottom: 16px">
        <a-col :span="16">
          <a-space>
            <a-button v-if="checkPermission(['adminrole/delete'])" type="primary" status="danger" @click="batchDel()">
              <template #icon><icon-delete /></template>批量删除
            </a-button>
            <a-button v-if="checkPermission(['adminrole/add'])" type="primary" @click="add()">
              <template #icon><icon-plus /></template>
              <template #default>添加</template>
            </a-button>
          </a-space>
        </a-col>
        <a-col :span="8" style="text-align: right">

        </a-col>
      </a-row>
      <a-table
        row-key="id"
        :loading="loading"
        :pagination="pagination"
        :data="renderData"
        :bordered="{ wrapper: true, cell: true }"
        :row-selection="rowSelection"
        :scroll="tableScroll"
        column-resizable
        @selection-change="selectionChange"
        @page-change="onPageChange"
        @page-size-change="onPageSizeChange"
      >
        <template #columns>
          <a-table-column title="ID" data-index="id" :sortable="{ sortDirections: ['ascend', 'descend'] }" align="center" fixed="left" :width="60"/>
          <a-table-column title="名称" data-index="name" align="center" :width="160"/>
          <a-table-column title="备注" data-index="remark" align="center" :width="200"/>
          <a-table-column title="排序" data-index="sorting" align="center" :width="80"/>
          <a-table-column title="启用" data-index="status" align="center" :width="80">
            <template #cell="{ record }">
              <a-switch v-model="record.status" :checked-value="1" :unchecked-value="2" @change="isActivate(record)"/>
            </template>
          </a-table-column>
          <a-table-column title="创建时间" data-index="created_at" :sortable="{ sortDirections: ['ascend', 'descend'] }" align="center" :width="180"/>
          <a-table-column title="操作" data-index="operations" align="center" fixed="right" :width="200">
            <template #cell="{ record }">
              <a-space>
                <a-button v-if="checkPermission(['adminrole/edit'])" type="primary" size="small" @click="edit(record)"><template #icon><icon-edit /></template>编辑</a-button>
                <a-button v-if="checkPermission(['adminrole/delete'])" type="primary" status="danger" size="small" @click="del([record])"><template #icon><icon-delete /></template>删除</a-button>
              </a-space>
            </template>
          </a-table-column>
        </template>
      </a-table>
    </a-card>

    <a-modal
      v-model:visible="dialogVisible"
      :title="dialogTitle"
      :ok-loading="btnLoading"
      :modal-style="modalStyle"
      :body-style="bodyStyle"
      :mask-closable="false"
      @cancel="dialogCancel"
      @before-ok="dialogBeforeOk"
    >
      <a-form ref="formRef" :model="formModel">
        <a-form-item field="status" label="是否启用">
          <a-switch v-model="formModel.status" :checked-value="1" :unchecked-value="2"/>
        </a-form-item>
        <a-form-item
          field="name"
          label="名称"
          required
          :validate-trigger="['change','input']"
          :rules="[
            {
              required: true,
              message: '名称不能为空',
            },
          ]"
        >
          <a-input v-model="formModel.name" placeholder="请输入名称"/>
        </a-form-item>
        <a-form-item field="remark" label="备注">
          <a-textarea v-model="formModel.remark" allow-clear :max-length="{ length: 120, errorOnly: true }" :auto-size="{ minRows: 5,maxRows: 8 }" show-word-limit/>
        </a-form-item>
        <a-form-item field="sort" label="排序">
          <a-input-number v-model="formModel.sorting" :style="{width:'100px'}"/>
        </a-form-item>
        <a-form-item
          field="access_ids"
          label="权限"
          :rules="[
            {
              required: true,
              message: '至少选择一个权限',
            },
            {
              type: 'array',
              minLength: 1,
              message: '至少选择一个权限',
            },
          ]"
        >
          <a-tree
            :checkable="true"
            :check-strictly="checkStrictly"
            v-model:checked-keys="checkedMenuIds"
            :data="treeMenus"
            :field-names="{ children: 'children', title: 'name', key: 'id' }"
            @check="menuCheck"
          />
        </a-form-item>
      </a-form>
    </a-modal>
  </div>
</template>

<script lang="ts" setup>
  import { ref, reactive, h, compile } from 'vue';
  import { useI18n } from 'vue-i18n';
  import { FormInstance } from '@arco-design/web-vue/es/form';
  import { Message, Modal } from '@arco-design/web-vue';

  import useLoading from '@/hooks/loading';
  import screenHeight from '@/utils/screen-height';
  import checkPermission from '@/utils/permission';
  import { Pagination } from '@/types/global';
  import { DataState, QueryParams, apiList, apiInfo, apiSave, apiDel, apiDisable } from '@/api/role';
  import { apiTreeList as apiMenuTree } from '@/api/menu';

  const { loading, setLoading } = useLoading(true);
  const { t } = useI18n();
  const height = screenHeight();
  const basePagination: Pagination = {
    current: 1,
    pageSize: 20,
    showTotal: true,
    showJumper: true,
    showPageSize: true,
    pageSizeOptions: [10, 20, 30, 50, 100, 150, 200, 300, 500],
  };
  const baseQuery = () => {
    return {
      page: 1,
      limit: 20,
      name: '',
      time_type: 'created_at',
      range_date: [],
    };
  };
  const baseFormModel = {
    id: '',
    created_at: '',
    updated_at: '',
    name: '',
    remark: '',
    access_ids: [],
    sorting: 100,
    status: 1,
  };
  const formRef = ref<FormInstance>();
  const renderData = ref<DataState[]>([]);
  const query = ref(baseQuery());
  const formModel = ref<any>(baseFormModel);
  const pagination = reactive({
    ...basePagination,
  });
  const rowSelection = reactive({
    type: 'checkbox' as const,
    selectedRowKeys: [] as any,
    showCheckedAll: true,
  });
  const tableScroll = ref({
    x: '100%',
    y: height,
  });
  const modalStyle = {
    width: '60%',
    height: '70%',
    maxWidth: '700px',
  };
  const bodyStyle = {
    height: 'calc(100% - 108px)',
    overflow: 'auto',
  };

  const isReset = ref(true); // 是否重置
  let selectionKeys: string[] = []; // 选中项ID
  const dialogVisible = ref(false);
  const dialogTitle = ref();
  const btnLoading = ref(false);

  const checkStrictly = ref(false);
  const checkedMenuIds = ref([]); // 选中的权限菜单
  const treeMenus = ref<any>([]); // 权限菜单

  // 分页
  const onPageChange = (page: number) => {
    isReset.value = false;
    fetchData({ ...query.value, page });
  };
  const onPageSizeChange = (limit: number) => {
    isReset.value = false;
    fetchData({ ...query.value, limit });
  };
  // 列表
  const fetchData = async (
    params: QueryParams = { ...query.value }
  ) => {
    setLoading(true);
    reset();
    try {
      const { data } = await apiList(params);
      renderData.value = data.data;
      query.value.page = params.page;
      query.value.limit = params.limit;
      pagination.current = params.page;
      pagination.pageSize = params.limit;
      pagination.total = data.total;
    } catch (err) {
      // you can report use errorHandler or other
    } finally {
      setLoading(false);
    }
  };
  // 添加
  const add = () => {
    dialogVisible.value = true;
    dialogTitle.value = '新增';
    menuTree();
    reset();
  };
  // 编辑
  const edit = async (row: DataState) => {
    dialogVisible.value = true;
    dialogTitle.value = `编辑: ${row.name}`;
    menuTree();
    reset();
    const { data } = await apiInfo({id: row.id});
    formModel.value = data;
    checkedMenuIds.value = data.access_ids;
  };
  // 删除
  const del = (row: any[]) => {
    if (!row.length) {
      selectMsg();
    } else {
      let title = '删除';
      let message = `确定要删除选中的 <span style="color:red">${row.length} </span> 条数据吗？`;
      let ids = row;
      if (row.length === 1 && row[0].id) {
        title = `${title}ID：${row[0].id}`;
        message = `确定要删除 <span style="color:red">${row[0].name} </span> 这条数据吗？`;
        ids = [row[0].id];
      }
      Modal.warning({
        title,
        content: () => h(compile(message)),
        closable: true,
        hideCancel: false,
        onOk: (async () => {
          setLoading(true);
          try {
            await apiDel({ids});
          } catch (err) {
            setLoading(false);
          } finally {
            fetchData({...query.value});
            setLoading(false);
          }
        }),
      });
    }
  };
  // 提交
  const submit = async (done: any) => {
    try {
      const ruleRes = await formRef.value?.validate();
      if (!ruleRes) {
        await apiSave(formModel.value);
        done();
        fetchData({...query.value});
      } else {
        done(false);
      }
    } catch (err) {
      done(false);
    } finally {
      done(false);
    }
  };
  // 重置
  const reset = async () => {
    // 表单重置
    formModel.value = baseFormModel;
    await formRef.value?.resetFields();
    checkedMenuIds.value = [];

    if (isReset.value) {
      rowSelection.selectedRowKeys = [];
      selectionKeys = [];
    } else {
      isReset.value = true;
    }
  };
  // 搜索
  const search = () => {
    query.value.page = 1;
    fetchData({...query.value} as unknown as QueryParams);
  };
  // 刷新
  const refresh = () => {
    query.value = baseQuery();
    fetchData({...query.value});
  };
  // 启用/禁用
  const isActivate = async (row: DataState) => {
    setLoading(true);
    await apiDisable({
      id: row.id,
      status: row.status,
    });
    fetchData({...query.value});
  };
  const menuTree = async () => {
    const { data } = await apiMenuTree({status: 1});
    treeMenus.value = data.data;
  };

  // 已选择的数据行发生改变时触发 -- table 表头
  const selectionChange = (rowKeys: any[]) => {
    rowSelection.selectedRowKeys = rowKeys;
    selectionKeys = rowKeys;
  };
  const selectMsg = (message?: string) => {
    Message.info(message || '请选择需要操作的数据');
  };
  // 批量删除
  const batchDel = () => {
    del(selectionKeys);
  };
  // 菜单选择
  const menuCheck = (checkedKeys: (string | number)[], data: unknown) => {
    formModel.value.access_ids = checkedKeys;
  };

  const dialogCancel = () => {
    dialogVisible.value = false;
  };
  const dialogBeforeOk = (done: any) => {
    submit(done);
    // done();
    // done(false);
  };

  fetchData();
</script>

<script lang="ts">
  export default {
    name: 'Role',
  };
</script>

<style scoped lang="less">
  :deep(.arco-table-th) {
    &:last-child {
      .arco-table-th-item-title {
        margin-left: 16px;
      }
    }
  }
</style>
